﻿using System.Reflection;

namespace Tools
{
    public class EnumExt
    {
        /// <summary>
        /// 获取枚举成员的自定义描述（如果有的话）
        /// 如果枚举项上定义了EnumDisplayNameAttribute特性，则返回其DisplayName，否则返回枚举项的名称
        /// </summary>
        /// <param name="e">枚举成员</param>
        /// <returns>枚举成员的描述</returns>
        public static string GetEnumDescription(object e)
        {
            // 获取枚举成员的类型信息
            Type t = e.GetType();
            // 获取枚举成员的所有字段
            FieldInfo[] ms = t.GetFields();
            // 遍历所有字段，查找与传入的枚举成员匹配的字段
            foreach (FieldInfo f in ms)
            {
                // 如果字段名称与枚举成员名称不同，继续循环
                if (f.Name != e.ToString())
                {
                    continue;
                }
                // 如果字段定义了EnumDisplayNameAttribute特性，则返回DisplayName属性的值
                if (f.IsDefined(typeof(EnumDisplayNameAttribute), true))
                {
                    var attributes = f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), true);
                    if (attributes.Length > 0 && attributes[0] is EnumDisplayNameAttribute attribute)
                    {
                        return attribute.DisplayName;
                    }
                }

            }
            // 如果没有找到特性，则返回枚举项的名称
            return e.ToString() ?? string.Empty;
        }

        /// <summary>
        /// 将枚举类型转换为列表，常用于生成下拉框选项
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <returns></returns>
        public static List<OptionItem>GetEnumOptions<TEnum>() where TEnum : struct, Enum
        {
            return Enum.GetValues(typeof(TEnum))
                .Cast<TEnum>()
                .Select(e => new OptionItem
                {
                    Text = GetEnumDescription(e),
                    Value = Convert.ToInt32(e).ToString()
                })
                .ToList();
        }


        /// <summary>
        /// 自定义特性，枚举成员的DisplayName属性用来设置枚举项的显示名称
        /// </summary>
        public class EnumDisplayNameAttribute : Attribute
        {
            private readonly string _displayName;

            // 构造函数接收一个显示名称
            public EnumDisplayNameAttribute(string displayName)
            {
                _displayName = displayName;
            }

            // 获取显示名称
            public string DisplayName
            {
                get
                {
                    return _displayName;
                }
            }
        }

        /// <summary>
        /// 将枚举类型转换为字典，字典的键为枚举项的描述，值为枚举的整数值
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <returns>返回枚举描述和对应值的字典</returns>
        public static Dictionary<string, int> ToDictionary(Type enumType)
        {
            Dictionary<string, int> dicItems = new Dictionary<string, int>();
            // 遍历枚举类型中的所有枚举值
            foreach (var e in Enum.GetValues(enumType))
            {
                // 将枚举的描述和对应的整数值添加到字典中
                dicItems.Add(GetEnumDescription(e), Convert.ToInt32(e));
            }
            return dicItems;
        }

        /// <summary>
        /// 根据枚举类型和传入的整数值返回相应的枚举项名称
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <param name="sV">枚举的整数值</param>
        /// <returns>返回对应整数值的枚举项名称</returns>
        public static string GetStringValue(Type enumType, string sV)
        {
            string returnvalue = "";
            // 遍历枚举类型中的所有枚举值
            foreach (var e in Enum.GetValues(enumType))
            {
                // 如果枚举值的整数值与传入的字符串值匹配，返回对应的枚举项名称
                if (Convert.ToInt16(e).ToString() == sV)
                {
                    returnvalue = e.ToString() ?? string.Empty;
                }
            }
            return returnvalue;
        }

        /// <summary>
        /// 根据枚举类型和枚举项名称返回对应的整数值
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <param name="sV">枚举项名称</param>
        /// <returns>返回枚举项的整数值</returns>
        public static int GetIntValue(Type enumType, string sV)
        {
            int returnvalue = 0;
            // 遍历枚举类型中的所有枚举值
            foreach (var item in Enum.GetValues(enumType))
            {
                // 如果枚举项名称匹配，则返回对应的整数值
                if (sV == item.ToString())
                    returnvalue = Convert.ToInt32(item);
            }
            return returnvalue;
        }
    }



    public class OptionItem
    {
        public string Text { get; set; }
        public string Value { get; set; }
    }

}
